"""Ingress资源提取器模块"""

from typing import Dict, Any, Optional, List
import yaml
import logging
from src.extractors.base import Extractor

class IngressExtractor(Extractor):
    """
    Ingress资源提取器
    负责从Ingress资源定义中提取关键信息
    """
    
    def __init__(self, logger: Optional[logging.Logger] = None):
        """初始化Ingress提取器"""
        super().__init__(logger)
        self.resource_type = "Ingress"
    
    def extract(self, content: str, file_path: str = "") -> Dict[str, Any]:
        """
        从Ingress YAML/JSON内容中提取信息
        
        Args:
            content: YAML/JSON格式的资源内容
            file_path: 资源文件路径，可选，用于日志记录
            
        Returns:
            提取的Ingress资源信息字典
        """
        # 解析YAML/JSON内容
        resource = self.parse_content(content, file_path)
        if not resource:
            return {}
            
        # 检查是否为Ingress资源
        if resource.get("kind") != "Ingress":
            self.logger.warning(f"资源不是Ingress: {file_path}")
            return {}
            
        # 提取基本信息
        result = self._extract_basic_info(resource)
        
        # 提取规则
        self._extract_rules(resource, result)
        
        # 提取TLS配置
        self._extract_tls_config(resource, result)
        
        # 提取默认后端
        self._extract_default_backend(resource, result)
        
        return result
    
    def _extract_basic_info(self, resource: Dict[str, Any]) -> Dict[str, Any]:
        """
        提取基本元数据信息
        
        Args:
            resource: 解析后的资源字典
            
        Returns:
            包含基本信息的字典
        """
        metadata = resource.get("metadata", {})
        spec = resource.get("spec", {})
        
        result = {
            "kind": "Ingress",
            "name": metadata.get("name", ""),
            "namespace": metadata.get("namespace", "default"),
            "creation_timestamp": metadata.get("creationTimestamp", "")
        }
        
        # 提取标签和注解
        if "labels" in metadata:
            result["labels"] = metadata.get("labels", {})
            
        if "annotations" in metadata:
            result["annotations"] = metadata.get("annotations", {})
        
        # 提取Ingress类
        if "ingressClassName" in spec:
            result["ingress_class_name"] = spec.get("ingressClassName")
        
        # 检查注解中是否有Ingress类
        if "annotations" in metadata and "kubernetes.io/ingress.class" in metadata.get("annotations", {}):
            result["ingress_class_annotation"] = metadata.get("annotations", {}).get("kubernetes.io/ingress.class")
            
        return result
    
    def _extract_rules(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取Ingress规则
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        spec = resource.get("spec", {})
        
        if "rules" in spec:
            rules = []
            for rule in spec.get("rules", []):
                rule_info = {}
                
                # 提取主机信息
                if "host" in rule:
                    rule_info["host"] = rule.get("host")
                
                # 提取HTTP路径
                if "http" in rule:
                    http_info = {"paths": []}
                    
                    for path in rule.get("http", {}).get("paths", []):
                        path_info = {}
                        
                        if "path" in path:
                            path_info["path"] = path.get("path")
                            
                        if "pathType" in path:
                            path_info["path_type"] = path.get("pathType")
                        
                        # 提取后端信息 - 支持v1beta1和v1的格式
                        if "backend" in path:
                            backend = path.get("backend", {})
                            
                            # v1 API格式
                            if "service" in backend:
                                service = backend.get("service", {})
                                path_info["backend"] = {
                                    "service": {
                                        "name": service.get("name", ""),
                                        "port": {}
                                    }
                                }
                                
                                port = service.get("port", {})
                                if "number" in port:
                                    path_info["backend"]["service"]["port"]["number"] = port.get("number")
                                    
                                if "name" in port:
                                    path_info["backend"]["service"]["port"]["name"] = port.get("name")
                            
                            # v1beta1 API格式
                            else:
                                path_info["backend"] = {
                                    "service_name": backend.get("serviceName", ""),
                                    "service_port": backend.get("servicePort", "")
                                }
                                
                        http_info["paths"].append(path_info)
                    
                    rule_info["http"] = http_info
                
                rules.append(rule_info)
            
            if rules:
                result["rules"] = rules
    
    def _extract_tls_config(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取TLS配置
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        spec = resource.get("spec", {})
        
        if "tls" in spec:
            tls_configs = []
            
            for tls in spec.get("tls", []):
                tls_info = {}
                
                if "hosts" in tls:
                    tls_info["hosts"] = tls.get("hosts", [])
                    
                if "secretName" in tls:
                    tls_info["secret_name"] = tls.get("secretName")
                
                tls_configs.append(tls_info)
            
            if tls_configs:
                result["tls"] = tls_configs
    
    def _extract_default_backend(self, resource: Dict[str, Any], result: Dict[str, Any]) -> None:
        """
        提取默认后端
        
        Args:
            resource: 解析后的资源字典
            result: 要填充的结果字典
        """
        spec = resource.get("spec", {})
        
        if "defaultBackend" in spec:
            backend = spec.get("defaultBackend", {})
            
            # v1 API格式
            if "service" in backend:
                service = backend.get("service", {})
                result["default_backend"] = {
                    "service": {
                        "name": service.get("name", "")
                    }
                }
                
                port = service.get("port", {})
                if port:
                    result["default_backend"]["service"]["port"] = {}
                    
                    if "number" in port:
                        result["default_backend"]["service"]["port"]["number"] = port.get("number")
                        
                    if "name" in port:
                        result["default_backend"]["service"]["port"]["name"] = port.get("name")
            
            # v1beta1 API格式
            else:
                result["default_backend"] = {
                    "service_name": backend.get("serviceName", ""),
                    "service_port": backend.get("servicePort", "")
                }
    
    def _to_snake_case(self, camel_case: str) -> str:
        """
        将驼峰命名转换为蛇形命名
        
        Args:
            camel_case: 驼峰命名的字符串
            
        Returns:
            蛇形命名的字符串
        """
        snake_case = ""
        for i, char in enumerate(camel_case):
            if char.isupper():
                if i > 0:
                    snake_case += "_"
                snake_case += char.lower()
            else:
                snake_case += char
        return snake_case
    
    def _clean_keys(self, data: Dict[str, Any]) -> Dict[str, Any]:
        """
        递归清理字典键为蛇形命名
        
        Args:
            data: 要清理的字典
            
        Returns:
            清理后的字典
        """
        result = {}
        
        if not isinstance(data, dict):
            return data
            
        for key, value in data.items():
            new_key = self._to_snake_case(key)
            
            if isinstance(value, dict):
                result[new_key] = self._clean_keys(value)
            elif isinstance(value, list):
                result[new_key] = [
                    self._clean_keys(item) if isinstance(item, dict) else item
                    for item in value
                ]
            else:
                result[new_key] = value
                
        return result
    
    def parse_content(self, content: str, file_path: str = "") -> Dict[str, Any]:
        """
        解析YAML/JSON内容
        
        Args:
            content: YAML/JSON格式的字符串内容
            file_path: 文件路径，用于记录日志
            
        Returns:
            解析后的字典
        """
        if isinstance(content, dict):
            return content
            
        try:
            return yaml.safe_load(content) or {}
        except yaml.YAMLError as e:
            self.logger.error(f"解析YAML失败: {file_path}, 错误: {str(e)}")
            return {}